package com.zmn.plat.admin.controller.product.tariff.item;

import com.alibaba.fastjson.JSON;
import com.google.common.collect.Lists;
import com.zmn.common.constant.GlobalConsts;
import com.zmn.common.dictionary.GlobalDict;
import com.zmn.common.dto2.ResponseDTO;
import com.zmn.common.utils.math.MathUtil;
import com.zmn.common.utils.number.NumberUtil;
import com.zmn.common.utils.office.ExcelUtil;
import com.zmn.manager.common.database.annotation.ReadOnlyConnection;
import com.zmn.plat.business.interfaces.channel.ChannelServiceCategoryBService;
import com.zmn.plat.business.interfaces.pilot.ChannelPriceBService;
import com.zmn.plat.business.interfaces.price.CommonBService;
import com.zmn.plat.business.interfaces.price.meter3.MeterFlow3CommonBService;
import com.zmn.plat.business.interfaces.price.meter3.MeterFlow3ItemBService;
import com.zmn.plat.business.interfaces.product.ProductBService;
import com.zmn.plat.business.interfaces.product.tariff.TariffProductBService;
import com.zmn.plat.business.interfaces.servcategory.ShowCategoryAssociationBService;
import com.zmn.plat.common.constant.ItemCategoryConsts;
import com.zmn.plat.common.constant.OnePriceConsts;
import com.zmn.plat.common.constant.ProductConsts;
import com.zmn.plat.common.dto.price.meter3.ItemDRO3;
import com.zmn.plat.common.dto.price.meter3.ItemPriceQuery3;
import com.zmn.plat.common.dto.price.meter3.ProductTariffTypeDRO;
import com.zmn.plat.common.dto.price.meter3.ProductTariffTypeQuery;
import com.zmn.plat.common.dto.product.item.ItemDRO;
import com.zmn.plat.common.enums.PilotConfigEnum;
import com.zmn.plat.common.exception.PlatException;
import com.zmn.plat.manager.dictionary.MasterDict;
import com.zmn.plat.manager.dictionary.ProductDict;
import com.zmn.plat.model.entity.area.AreaQuery;
import com.zmn.plat.model.entity.area.BaseArea;
import com.zmn.plat.model.entity.brand.BaseBrand;
import com.zmn.plat.model.entity.channel.Channel;
import com.zmn.plat.model.entity.channel.ChannelQuery;
import com.zmn.plat.model.entity.channel.ChannelServiceArea;
import com.zmn.plat.model.entity.pilot.SupportPilotVO;
import com.zmn.plat.model.entity.product.ServProduct;
import com.zmn.plat.model.entity.servcategory.ServAssCategoryQuery;
import com.zmn.plat.model.entity.servcategory.ShowCategoryAssociation;
import com.zmn.plat.model.entity.servcategory.ShowCategoryAssociationQuery;
import com.zmn.plat.model.entity.servcategory.ShowCategoryAssociationVO;
import com.zmn.plat.model.entity.service.tariff.ServiceTariff;
import com.zmn.plat.model.vo.brand.factor.BrandFactorRatioVo;
import com.zmn.plat.model.vo.channel.ChannelServProductVO;
import com.zmn.plat.model.vo.channel.ChannelServiceAreaProductCategoryVo;
import com.zmn.plat.model.vo.product.tariff.item.price.ProductServiceItemExcutePriceQueryVo;
import com.zmn.plat.model.vo.product.tariff.item.price.ProductServiceItemExcutePriceResultVo;
import com.zmn.plat.model.vo.servcategory.ServAssCategoryVO;
import com.zmn.plat.services.interfaces.area.BaseAreaService;
import com.zmn.plat.services.interfaces.brand.BaseBrandService;
import com.zmn.plat.services.interfaces.channel.*;
import com.zmn.plat.services.interfaces.product.ServProductService;
import com.zmn.plat.services.interfaces.servcategory.ServAssCategoryService;
import com.zmn.plat.services.interfaces.servcategory.ShowCategoryAssociationService;
import com.zmn.plat.services.interfaces.service.tariff.ServiceTariffService;
import com.zmn.plat.utils.bean.BeanCopyUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cglib.beans.BeanCopier;
import org.springframework.cglib.core.Converter;
import org.springframework.stereotype.Controller;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 产品故障项目表，从故障分组的项目中选择
 *
 * @author linfeng
 * @since 2019-11-21 18:57:24
 */
@RequestMapping("/product/tariff/item/")
@Controller
public class ProductTariffGroupItemListController extends ProductTariffGroupItemBaseController {
    protected Logger logger = LoggerFactory.getLogger(this.getClass());

    private static final long serialVersionUID = -3836869134272014901L;
    @Resource
    private ChannelService channelService;
    @Resource
    private ChannelServiceAreaService channelServiceAreaService;
    @Resource
    private ChannelServiceAreaCategoryService channelServiceAreaCategoryService;
    @Resource
    private ChannelServiceCategoryService channelServiceCategoryService;
    @Resource
    private ChannelServProductService channelServProductService;
    @Resource
    private ChannelPriceBService channelPriceBService;
    @Resource
    private ShowCategoryAssociationService showCategoryAssociationService;
    @Resource
    private TariffProductBService tariffProductBService;
    @Resource
    private ServAssCategoryService servAssCategoryService;
    @Resource
    private ServProductService servProductService;
    @Resource
    private ProductBService productBService;
    @Resource
    private BaseBrandService baseBrandService;
    @Resource
    private BaseAreaService baseAreaService;
    @Resource
    private ChannelServiceCategoryBService channelServiceCategoryBService;
    @Resource
    ShowCategoryAssociationBService showCategoryAssociationBService;
    @Resource
    CommonBService commonBService;
    @Resource
    MeterFlow3CommonBService meterFlow3CommonBService;
    @Resource
    MeterFlow3ItemBService meterFlow3ItemBService;
    @Resource
    ServiceTariffService serviceTariffService;

    // 重庆的城市id
    private final int CQ_CITY_ID = 500100;
    // 默认品牌 其他
    private final int BRAND_ID = 1051;

    /**
     * 执行价
     *
     * @param query
     * @author linfeng
     * @since 2019-11-21 18:57:24
     */
    @RequestMapping(value = "price")
    @RequiresPermissions("/product/tariff/item/price.action")
    @ReadOnlyConnection
    public ModelAndView pricePage(@ModelAttribute ProductServiceItemExcutePriceQueryVo query) {
        ModelAndView mav = new ModelAndView("product/service/item/price/list");
        List<ChannelServiceAreaProductCategoryVo> productCategories = new ArrayList<>();
        List<ChannelServProductVO> productList = new ArrayList<>();
        List<ChannelServiceAreaProductCategoryVo> servCategList = new ArrayList<>();
        List<ChannelServiceAreaProductCategoryVo> categOneList = new ArrayList<>();
        List<ChannelServiceAreaProductCategoryVo> categList = new ArrayList<>();
        List<ProductServiceItemExcutePriceResultVo> items = new ArrayList<>();
        List<ChannelServiceArea> baseAreas = new ArrayList<>();
        List<BrandFactorRatioVo> brands = new ArrayList<>();

        boolean isFistIn = NumberUtil.isNullOrZero(query.getChannelId());
        if (isFistIn) {
            if (Objects.isNull(query.getBizType())) {
                query.setBizType(ProductConsts.BIZ_TYPE_C);
            }
        }

        if (Objects.isNull(query.getShowType())) {
            query.setShowType(ProductDict.ERP_PRODUCT_TYPE);
        }

        // 渠道
        ChannelQuery channelQuery = new ChannelQuery();
        channelQuery.setStatus(GlobalConsts.YES);
        channelQuery.setRank(GlobalConsts.YES);
        List<Channel> channels = channelService.listByQuery(channelQuery);
        if (isFistIn) {
            query.setChannelId(channels.get(0).getChannelId());
        }

        Integer avaliableChannelId = null;
        try {
            query.setCurrentChannelId(query.getChannelId());
            // 当前渠道是否存在合法的开通分类，不存在则变换渠道id为父级的渠道id
            avaliableChannelId = channelServiceCategoryBService.getAvailableCategoryChannelId(query.getChannelId());
            query.setChannelId(avaliableChannelId);
        } catch (PlatException e) {
            logger.error("渠道没配置可用的分类", e);
        }


        // 品牌取基础配置的所有品牌
        List<BaseBrand> list = baseBrandService.listAll();
        brands = list.stream().map(e -> {
            BrandFactorRatioVo vo = new BrandFactorRatioVo();
            vo.setBrandId(e.getBrandId());
            vo.setBrandName(e.getName());
            return vo;
        }).collect(Collectors.toList());

        if (NumberUtil.isNullOrZero(query.getBrandId())) {
            query.setBrandId(BRAND_ID);
        }
        //查询可用的分类出错或者不存在可用度额分类
        if (Objects.nonNull(avaliableChannelId)) {
            // 城市,默认选择重庆，取渠道开通的城市,允许渠道不配置城市
            baseAreas = channelServiceAreaService.listCityByChannelId(query.getChannelId());
            if (CollectionUtils.isEmpty(baseAreas)) {
                baseAreas = getALLBaseAreas();
            }

            // 如果渠道存在开通的服务区域，检查是否包含重庆，如果包含，那么采取重庆为当前城市
            boolean noCityId = NumberUtil.isNullOrZero(query.getCityId());
            if (noCityId && !CollectionUtils.isEmpty(baseAreas)) {
                List<ChannelServiceArea> cityCqing =
                        baseAreas.stream().filter(e -> e.getCityId().equals(CQ_CITY_ID)).collect(Collectors.toList());
                if (!CollectionUtils.isEmpty(cityCqing)) {
                    query.setCityId(CQ_CITY_ID);
                } else {
                    query.setCityId(baseAreas.get(0).getCityId());
                }
            }

            // 后续步骤进行的前提是城市存在，城市不存在，这没有数据显示
            if (NumberUtil.isPositiveInteger(query.getCityId())) {
                // Channel currentChannel = channelService.findByKey(query.getChannelId());
                // query.setPlat(currentChannel.getPlat());
                // 城市存在开通的类型，取城市下的开通产品类型，不存在取渠道的产品类型
                // 只有前台分类
                productCategories = channelServiceAreaCategoryService.listByChannelIdAndCityIdAndShowType(query.getChannelId(),
                        query.getCityId(), ProductDict.EC_PRODUCT_TYPE);
                // 当前城市没有开通服务分类，渠道的服务分类
                if (CollectionUtils.isEmpty(productCategories)) {
                    // 只有前台分类
                    productCategories =
                            channelServiceCategoryService.listByChannelIdAndShowType(query.getChannelId(), ProductDict.EC_PRODUCT_TYPE);
                }
                // 都不存在，取基础数据的所有前台分类
                if (CollectionUtils.isEmpty(productCategories)) {
                    productCategories = getAllBaseCategs();
                }

                // 服务分类，默认第一个
                if (!CollectionUtils.isEmpty(productCategories)) {
                    listCategoriesAndSetQueryCategoryId(productCategories, servCategList, categOneList, categList, query);
                    // 渠道关联表存在的，状态必须为启用，如果为禁用的，那么不会出现在产品列表中(新业务类型，没有显示平台的概念，去掉显示平台限制)
                    productList = channelServProductService.listProductByPriceQuery(query);
                    // 需要根据产品类型和价格表类型过滤可以使用的产品
                    // filterProduct(productList,query);
                }
                // 获取品牌，先查询渠道是否配置了品牌，渠道配置了品牌，以渠道为主否则以基础的为主,4.21取消了渠道联动品牌
                // brands = listBrandRatio(query.getChannelId(), query.getKeepType());

                // 表格数据
                if (!CollectionUtils.isEmpty(productList)) {
                    if (!NumberUtil.isPositiveInteger(query.getProductId())) {
                        ChannelServProductVO product = productList.get(0);
                        query.setProductId(product.getProductId());
                    }
                    // 根据分类和产品类型确定价格表（优先支持计价器，不支持计价器走服务项）
                    setTariffType(query);
                    if (Objects.equals(ProductDict.TRIFF_TYPE_TARIFF3, query.getTariffType())) {
                        String tariffName = null;
                        if (Objects.nonNull(query.getTariffId())) {
                            ServiceTariff tariff = serviceTariffService.findByKeyWithCache(query.getTariffId());
                            tariffName = Objects.isNull(tariff) ? null : tariff.getTariffName();
                        }
                        ItemPriceQuery3 itemPriceQuery3 = new ItemPriceQuery3();
                        BeanCopyUtils.copyProperties(query, itemPriceQuery3);
                        List<ItemDRO3> itemDRO3s = meterFlow3ItemBService.listItemPriceTransByQuery(itemPriceQuery3);
                        query.setTotalCount(itemDRO3s.size());
                        for (ItemDRO3 itemDRO3 : itemDRO3s) {
                            ProductServiceItemExcutePriceResultVo item = new ProductServiceItemExcutePriceResultVo();
                            BeanCopyUtils.copyProperties(itemDRO3, item);
                            item.setTariffType(query.getTariffType());
                            item.setTariffName(tariffName);
                            item.setPriceStr(narrow(itemDRO3.getPrice()));
                            item.setInternalSettlementPriceStr(narrow(itemDRO3.getInternalSettlementPrice()));
                            item.setExternalSettlementPriceStr(narrow(itemDRO3.getExternalSettlementPrice()));
                            items.add(item);
                        }
                        // 内存分页
                        items = items
                                .stream()
                                .sorted(Comparator.comparing(ProductServiceItemExcutePriceResultVo::getProductId))
                                .skip((long) (query.getPageIndex() - 1) * query.getPageSize())
                                .limit(query.getPageSize())
                                .collect(Collectors.toList());
                    } else {
                        items = tariffProductBService.listByExcuteQuery(query);
                    }
                }
            } else {
                logger.info("不存在城市，返回数据为空");
            }
        }


        mav.addObject("channels", channels);
        mav.addObject("baseAreas", baseAreas);
        // 服务分类联动数据
        mav.addObject("servCategories", servCategList);
        mav.addObject("categOneList", categOneList);
        mav.addObject("categList", categList);
        mav.addObject("productList", productList);
        mav.addObject("items", items);
        mav.addObject("brands", brands);
        mav.addObject("vo", query);
        return mav;
    }

    /**
     * 渠道模糊查询
     *
     * @param name
     * @author tanbiao
     * @since 2019-11-21 18:57:24
     */
    @RequestMapping(value = "listChannelByName")
    @ResponseBody
    public ResponseDTO listChannelByName(String name) {
        ChannelQuery channelQuery = new ChannelQuery();
        channelQuery.setStatus(GlobalConsts.YES);
        channelQuery.setRank(GlobalConsts.YES);
        channelQuery.setKeyword(name);
        channelQuery.setPageSize(ItemCategoryConsts.DEFAULT_SELECT_PAGE_SIZE);
        List<Channel> channels = channelService.listPageByQuery(channelQuery, null);
        return ResponseDTO.success(channels);
    }

    // ===============================================================以下为列表联动====================================
    // 1.渠道联动：城市（可能不存在），服务分类，一二级分类，产品
    // 2.城市联动：服务分类，一二级分类，产品
    // 3.服务分类联动：一二级分类，产品
    // 4.一级分类：二级分类，产品
    // 5.二级分类：产品
    // 6.产品类型联动：一二级分类，产品

    /**
     * 渠道联动：城市（可能不存在），服务分类，一二级分类，产品
     *
     * @param query
     * @author tanbiao
     * @since 2019-11-21 18:57:24
     */
    @RequestMapping(value = "loadChannelProducts")
    @ResponseBody
    public ResponseDTO loadChannelProducts(@RequestBody ProductServiceItemExcutePriceQueryVo query) {
        Map<String, Object> result = new HashMap<>();
        List<ChannelServProductVO> productList = new ArrayList<>();
        List<ChannelServiceAreaProductCategoryVo> servCategList = new ArrayList<>();
        List<ChannelServiceAreaProductCategoryVo> categOneList = new ArrayList<>();
        List<ChannelServiceAreaProductCategoryVo> categList = new ArrayList<>();
        List<ChannelServiceAreaProductCategoryVo> productCategories = new ArrayList<>();
        // List<BrandFactorRatioVo> brands = new ArrayList<>();
        Integer avaliableChannelId = null;
        try {
            query.setCurrentChannelId(query.getChannelId());
            // 当前渠道是否存在合法的开通分类，不存在则变换渠道id为父级的渠道id
            avaliableChannelId = channelServiceCategoryBService.getAvailableCategoryChannelId(query.getChannelId());
            query.setChannelId(avaliableChannelId);
        } catch (PlatException e) {
            logger.error("可用的分类不存在", e);
        }

        if (Objects.nonNull(avaliableChannelId)) {
            // 选择渠道触发整体变更
            if (query.getFlag() != null && query.getFlag() == 1) {
                // 城市,可能不存在
                List<ChannelServiceArea> baseAreas = channelServiceAreaService.listCityByChannelId(query.getChannelId());
                if (CollectionUtils.isEmpty(baseAreas)) {
                    baseAreas = getALLBaseAreas();
                }
                // 如果不为空的话
                if (!CollectionUtils.isEmpty(baseAreas)) {
                    List<ChannelServiceArea> cityCqing =
                            baseAreas.stream().filter(e -> e.getCityId().equals(CQ_CITY_ID)).collect(Collectors.toList());
                    if (!CollectionUtils.isEmpty(cityCqing)) {
                        query.setCityId(CQ_CITY_ID);
                        result.put("selectCity", query.getCityId());
                    } else {
                        query.setCityId(baseAreas.get(0).getCityId());
                    }
                }
                result.put("baseAreas", baseAreas);
            }
            // 后续步骤依赖渠道配置的城市，如果不存在配置的城市，那么数据为空
            if (NumberUtil.isPositiveInteger(query.getCityId())) {
                // 城市存在开通的类型，取城市下的开通产品类型，不存在取渠道的产品类型
                productCategories = channelServiceAreaCategoryService.listByChannelIdAndCityIdAndShowType(query.getChannelId(),
                        query.getCityId(), ProductDict.EC_PRODUCT_TYPE);
                // 当前城市没有开通服务分类，渠道的服务分类,城市必须配置
                if (CollectionUtils.isEmpty(productCategories)) {
                    productCategories =
                            channelServiceCategoryService.listByChannelIdAndShowType(query.getChannelId(), ProductDict.EC_PRODUCT_TYPE);
                }
                // 都不存在，取基础数据的所有前台分类
                if (CollectionUtils.isEmpty(productCategories)) {
                    productCategories = getAllBaseCategs();
                }
                // 服务分类，默认第一个
                if (!CollectionUtils.isEmpty(productCategories)) {
                    listCategoriesAndSetQueryCategoryId(productCategories, servCategList, categOneList, categList, query);
                    // // 根据分类和产品类型确定价格表（优先支持计价器，不支持计价器走服务项）
                    // setTariffType(query);
                    // 渠道关联表存在的，状态必须为启用，如果为禁用的，那么不会出现在产品列表中
                    productList = channelServProductService.listProductByPriceQuery(query);
                    // 加载可用的数据
                    // filterProduct(productList,query);
                }
                // brands = listBrandRatio(query.getChannelId(), query.getKeepType());
            } else {
                logger.info("城市数据不存在");
            }
        }


        result.put("servCategories", servCategList);
        result.put("categOneList", categOneList);
        result.put("categList", categList);
        result.put("productList", productList);
        // result.put("brands", brands);
        return ResponseDTO.success(result);
    }
    // ============================ 联动结束================================================

    /**
     * 描述: excel导出
     *
     * @param response 返回对象
     * @return void
     * @author tanbiao
     * @since 2019-11-21 18:57:24
     **/
    @RequestMapping("outputExcel")
    @RequiresPermissions("/product/tariff/item/price.action")
    @ReadOnlyConnection
    public void outputExcel(HttpServletResponse response, ProductServiceItemExcutePriceQueryVo query) throws UnsupportedEncodingException {
        List<ProductServiceItemExcutePriceResultVo> items = new ArrayList<>();
        Integer avaliableChannelId = null;
        try {
            query.setCurrentChannelId(query.getChannelId());
            // 当前渠道是否存在合法的开通分类，不存在则变换渠道id为父级的渠道id
            avaliableChannelId = channelServiceCategoryBService.getAvailableCategoryChannelId(query.getChannelId());
            query.setChannelId(avaliableChannelId);
            query.setPageSize(getExportPageLimit(response));
            query.setPageIndex(1);
            setTariffType(query);
            if (Objects.equals(ProductDict.TRIFF_TYPE_TARIFF3, query.getTariffType())) {
                String tariffName = null;
                if (Objects.nonNull(query.getTariffId())) {
                    ServiceTariff tariff = serviceTariffService.findByKeyWithCache(query.getTariffId());
                    tariffName = Objects.isNull(tariff) ? null : tariff.getTariffName();
                }
                ItemPriceQuery3 itemPriceQuery3 = new ItemPriceQuery3();
                BeanCopyUtils.copyProperties(query, itemPriceQuery3);
                List<ItemDRO3> itemDRO3s = meterFlow3ItemBService.listItemPriceTransByQuery(itemPriceQuery3);
                for (ItemDRO3 itemDRO3 : itemDRO3s) {
                    ProductServiceItemExcutePriceResultVo item = new ProductServiceItemExcutePriceResultVo();
                    BeanCopyUtils.copyProperties(itemDRO3, item);
                    item.setTariffType(query.getTariffType());
                    item.setTariffName(tariffName);
                    item.setPriceStr(String.valueOf(itemDRO3.getPrice()));
                    item.setInternalSettlementPriceStr(String.valueOf(itemDRO3.getInternalSettlementPrice()));
                    item.setExternalSettlementPriceStr(String.valueOf(itemDRO3.getExternalSettlementPrice()));
                    items.add(item);
                }
            } else {
                items = tariffProductBService.listByExcuteQuery(query);
            }
        }catch (PlatException e){
            logger.error("可用的分类不存在.",e);
        }

        String[] rowHead = {"价格表ID", "价格表名称", "价格表类型", "保内/保外", "服务分类", "一级产品分类", "二级产品分类", "产品ID", "产品名称", "产品状态", "项目分组ID", "项目分组名称",
                "项目ID", "项目名称", "销售价", "内部价", "外部价", "区分明细", "交通费", "工时费", "技术服务费", "配件包干费", "一口价", "单位", "最大数量", "默认项目", "互斥性", "城市系数", "品牌系数",
                "项目类型名称", "修改价格", "APP编辑", "APP显示", "工程师拍照", "项目状态", "明细类型", "材料费", "工艺费", "阶梯值", "阶梯降幅", "底折"};
        ArrayList<List> arrayList = Lists.newArrayListWithExpectedSize(items.size());
        arrayList.add(Arrays.asList(rowHead));
        if (CollectionUtils.isEmpty(items)) {
            items = new ArrayList<>();
            items.add(new ProductServiceItemExcutePriceResultVo());
        } else {
            items.forEach(coupItem -> {
                List<Object> list = new ArrayList<>();
                list.add(coupItem.getTariffId());
                list.add(coupItem.getTariffName());
                list.add(Objects.equals(coupItem.getTariffType(), GlobalConsts.NO) ? "服务价格" : "计价器价格");// 1服务2计价器
                list.add(com.zmn.plat.common.dictionary.ProductDict.getBizTypeCNENName(query.getBizType()));// 1保外2保内
                list.add(coupItem.getServCategName());
                list.add(coupItem.getCategOneName());
                list.add(coupItem.getCategName());
                list.add(coupItem.getProductId());
                list.add(coupItem.getProductName());
                list.add(Objects.equals(coupItem.getProductStatus(), GlobalConsts.NO) ? "禁用" : "启用");// 1禁用2启用
                list.add(coupItem.getGroupId());
                list.add(coupItem.getGroupName());
                list.add(coupItem.getItemId());
                list.add(coupItem.getItemName());
                list.add(coupItem.getPriceStr());
                list.add(coupItem.getInternalSettlementPriceStr());
                list.add(coupItem.getExternalSettlementPriceStr());
                list.add(Objects.equals(coupItem.getPriceSplit(), GlobalConsts.NO) ? "不区分" : "区分");
                list.add(coupItem.getTrafficFeeStr());
                list.add(coupItem.getHourFeeStr());
                list.add(coupItem.getServicePriceStr());
                list.add(coupItem.getPartPriceStr());
                list.add(Objects.equals(coupItem.getPriceStandard(), GlobalConsts.NO) ? "非一口价" : "一口价");
                list.add(coupItem.getUnit());
                list.add(NumberUtil.isNullOrZero(coupItem.getCountLimit()) ? "不限" : coupItem.getCountLimit());
                list.add(Objects.equals(coupItem.getGeneral(), GlobalConsts.NO) ? "非默认" : "默认");
                list.add(Objects.equals(coupItem.getMutexMode(), GlobalConsts.NO) ? "全局互斥"
                        : (Objects.equals(coupItem.getMutexMode(), GlobalConsts.YES) ? "局部互斥" : "不互斥"));
                list.add(Objects.equals(coupItem.getCityLimit(), GlobalConsts.NO) ? "不影响" : "影响");
                list.add(Objects.equals(coupItem.getBrandLimit(), GlobalConsts.NO) ? "不影响" : "影响");
                list.add(coupItem.getFaultCategName());
                list.add(Objects.equals(coupItem.getManualPrice(), GlobalConsts.NO) ? "不修改" : "修改");
                list.add(Objects.equals(coupItem.getEditEnable(), GlobalConsts.NO) ? "不编辑" : "编辑");
                list.add(Objects.equals(coupItem.getShow(), GlobalConsts.NO) ? "不显示" : "显示");
                list.add(Objects.equals(coupItem.getTakePicture(), GlobalConsts.NO) ? "不拍照" : "拍照");
                list.add(Objects.equals(coupItem.getItemStatus(), GlobalConsts.NO) ? "禁用" : "启用");
                // 明细类型
                list.add(Objects.isNull(coupItem.getPriceSplitType()) ? "--"
                        : (Objects.equals(coupItem.getPriceSplitType(), GlobalConsts.NO) ? "明细一" : "明细二（阶梯价）"));
                // 材料费
                list.add(Objects.isNull(coupItem.getMaterialFee()) ? "--" : coupItem.getMaterialFee() + "%");
                // 工艺费
                list.add(Objects.isNull(coupItem.getMaterialFee()) ? "--" : (100 - coupItem.getMaterialFee()) + "%");
                // 阶梯值
                list.add(Objects.isNull(coupItem.getNumberStep()) ? "--" : coupItem.getNumberStep());
                // 阶梯值降幅
                list.add(Objects.isNull(coupItem.getNumberStepDown()) ? "--" : coupItem.getNumberStepDown());
                // 底折
                list.add(Objects.isNull(coupItem.getBaseDiscount()) ? "--" : coupItem.getBaseDiscount());
                arrayList.add(list);
            });
        }
        String name = "执行价格.xlsx";
        name = new String(name.getBytes(), "ISO8859-1");
        try {
            ExcelUtil.export(response, arrayList, name, "sheet");
        } catch (Exception e) {
            logger.error("导出excel出错" + e.getMessage(), e);
        }

    }

    private void convertShowCateg(List<ChannelServiceAreaProductCategoryVo> productCategories,
                                  final List<ChannelServiceAreaProductCategoryVo> servCategList, final List<ChannelServiceAreaProductCategoryVo> categOneList,
                                  final List<ChannelServiceAreaProductCategoryVo> categList, ProductServiceItemExcutePriceQueryVo query) {
        BeanCopier copierServAssCategoryVO = BeanCopier.create(ServAssCategoryVO.class, ChannelServiceAreaProductCategoryVo.class, true);
        List<Integer> servCategIds = new ArrayList<>();
        productCategories.stream().forEach(e -> {
            if (!servCategIds.contains(e.getServCategId())) {
                servCategIds.add(e.getServCategId());
                servCategList.add(e);
            }
        });
        // 存在服务分类，加载与之对应的服务分类下的后台分类
        if (!NumberUtil.isPositiveInteger(query.getServCategId())) {
            query.setServCategId(servCategList.get(0).getServCategId());
        }
        // 后台服务分类加载后台一二级分类
        ServAssCategoryQuery servAssCategoryQuery = new ServAssCategoryQuery();
        servAssCategoryQuery.setServCategId(query.getServCategId());
        servAssCategoryQuery.setShowType(ProductConsts.ERP_PRODUCT_TYPE);
        List<ServAssCategoryVO> productCategList = servAssCategoryService.listByQuery(servAssCategoryQuery);
        List<Integer> categOneIdList = new ArrayList<>();
        List<Integer> categIdList = new ArrayList<>();
        // 一级分类
        productCategList.stream().forEach(e -> {
            if (!categOneIdList.contains(e.getCategOneId())) {
                categOneIdList.add(e.getCategOneId());
                ChannelServiceAreaProductCategoryVo vo = new ChannelServiceAreaProductCategoryVo();
                copierServAssCategoryVO.copy(e, vo, getConvert());
                categOneList.add(vo);
            }
        });
        if (!NumberUtil.isPositiveInteger(query.getCategOneId())) {
            query.setCategOneId(categOneList.get(0).getCategOneId());
        }
        // 二级分类
        productCategList.stream().filter(e -> Objects.equals(e.getCategOneId(), query.getCategOneId())).forEach(e -> {
            if (!categIdList.contains(e.getCategId())) {
                categIdList.add(e.getCategId());
                ChannelServiceAreaProductCategoryVo vo = new ChannelServiceAreaProductCategoryVo();
                copierServAssCategoryVO.copy(e, vo, getConvert());
                categList.add(vo);
            }
        });
        if (!NumberUtil.isPositiveInteger(query.getCategId())) {
            query.setCategId(categList.get(0).getCategId());
        }
    }

    /**
     * 功能描述 :检查试点配置，优先支持计价器，不支持计价器走服务项
     *
     * @param query
     * @return void
     * @author tanbiao
     * @modifier
     * @since 2020/3/30
     */
    private void setTariffType(ProductServiceItemExcutePriceQueryVo query) {
//        query.setTariffType(ProductDict.TRIFF_TYPE_SERVICE);
//        // // 先检查基础数据是否满足计价器条件：前台产品开启，计价器产品开启，有价格表等
//        // boolean isTariff = productBService.checkTariffByProductIdAndShowType(query.getProductId(), query.getCurrentChannelId(),
//        //     query.getShowType(), query.getBizType());
//        // if (!isTariff) {
//        //     logger.info("========================基础数据不支持计价器，那么支持服务项========");
//        //     return;
//        // }
//        // 不是同一渠道id那么分类为上级的，但是试点要走自己渠道的
//        Integer productChannelId = query.getCurrentChannelId();
//        if (!Objects.equals(query.getCurrentChannelId(), query.getChannelId())) {
//            productChannelId = query.getChannelId();
//        }
//
//        // 基础支持，检查试点
//        if (Objects.equals(query.getShowType(), ProductDict.EC_PRODUCT_TYPE)) {
//            boolean isTariff = channelPriceBService.checkByChannelIdAndCityIdAndTypeAndCateg(query.getCurrentChannelId(), query.getCityId(),
//                    OnePriceConsts.TARIFF, query.getServCategId(), query.getCategId());
//            if (isTariff) {
//                isTariff = productBService.checkTariffByProductIdAndShowType(query.getProductId(), productChannelId,
//                        query.getShowType(), query.getBizType());
//                if (isTariff) {
//                    query.setTariffType(ProductDict.TRIFF_TYPE_TARIFF);
//                }
//
//            }
//            logger.info("========================前台产品isTariff={}", isTariff);
//        } else {
//            ServProduct product = servProductService.findShowProductByBackProductId(query.getProductId());
//            // 二者都是开启状态，检查是否支持渠道试点
//            ShowCategoryAssociationQuery showCategoryAssociationQuery = new ShowCategoryAssociationQuery();
//            showCategoryAssociationQuery.setShowCategId(product.getCategId());
//            showCategoryAssociationQuery.setShowCategOneId(product.getCategOneId());
//            showCategoryAssociationQuery.setShowServCategId(product.getServCategId());
//            showCategoryAssociationQuery.setCategId(query.getCategId());
//            showCategoryAssociationQuery.setCategOneId(query.getCategOneId());
//            showCategoryAssociationQuery.setServCategId(query.getServCategId());
//            List<ShowCategoryAssociation> associationList = showCategoryAssociationService.listByQuery(showCategoryAssociationQuery);
//            if (CollectionUtils.isEmpty(associationList)) {
//                logger.error("关联关系不存在，数据有误，返回空列表........");
//                query.setTariffType(null);
//                return;
//            }
//            ShowCategoryAssociation showCategoryAssociation = associationList.get(0);
//            logger.info("showCategoryAssociation={}", JSON.toJSONString(showCategoryAssociation));
//            boolean isTariff = channelPriceBService.checkByChannelIdAndCityIdAndTypeAndCateg(query.getCurrentChannelId(), query.getCityId(),
//                    OnePriceConsts.TARIFF, showCategoryAssociation.getShowServCategId(), showCategoryAssociation.getShowCategId());
//            if (isTariff) {
//                isTariff = productBService.checkTariffByProductIdAndShowType(query.getProductId(), productChannelId,
//                        query.getShowType(), query.getBizType());
//                if (isTariff) {
//                    query.setTariffType(ProductDict.TRIFF_TYPE_TARIFF);
//                }
//            }
//            logger.info("后台产品isTariff={}", isTariff);
//        }


//        query.setTariffType(ProductDict.TRIFF_TYPE_SERVICE);
//        Integer channelId = query.getChannelId();
//        Integer cityId = query.getCityId();
//        Integer bizType = query.getBizType();
//        Integer showType = query.getShowType();
//        Integer servCategId = query.getServCategId();
//        Integer categId = query.getCategId();
//        Integer productId = query.getProductId();
//
//        // 如果是后端产品，转换成前端产品分类
//        if (Objects.equals(showType, ProductConsts.ERP_PRODUCT_TYPE)) {
//            List<ShowCategoryAssociationVO> showCategoryAssociationVOS =
//                    showCategoryAssociationBService.listByCategoryId(servCategId, query.getCategOneId(), categId);
//            if (!CollectionUtils.isEmpty(showCategoryAssociationVOS)) {
//                servCategId = showCategoryAssociationVOS.get(0).getShowServCategId();
//                categId = showCategoryAssociationVOS.get(0).getShowCategId();
//            }
//        }

//        // 计价器试点
//        Boolean pilotFlagTa = channelPriceBService.checkByChannelIdAndCityIdAndTypeAndCateg(channelId, cityId, OnePriceConsts.TARIFF, servCategId, categId);
//        if (!pilotFlagTa) {
//            return;
//        }
//
//        // 提前付试点
//        Boolean pilotFlagAd = channelPriceBService.checkByChannelIdAndCityIdAndTypeAndCateg(channelId, cityId, PilotConfigEnum.PAY_ADVANCE.getType(), servCategId, categId);
//        if (pilotFlagAd) {
//            // 查询提前付价格
//            Map<Integer, Integer> advanceMap = commonBService.getTariff(channelId, Arrays.asList(productId), showType, bizType, ProductDict.TRIFF_TYPE_ADVANCE);
//            if (!CollectionUtils.isEmpty(advanceMap)) {
//                query.setTariffType(ProductDict.TRIFF_TYPE_ADVANCE);
//                return;
//            }
//        }
//
//        // 查询计价器价格
//        Map<Integer, Integer> traiffMap = commonBService.getTariff(channelId, Arrays.asList(productId), showType, bizType, ProductDict.TRIFF_TYPE_TARIFF);
//        if (!CollectionUtils.isEmpty(traiffMap)) {
//            query.setTariffType(ProductDict.TRIFF_TYPE_TARIFF);
//        }

        ProductTariffTypeQuery typeQuery = new ProductTariffTypeQuery();
        BeanCopyUtils.copyProperties(query, typeQuery);
        typeQuery.setProductIdList(Arrays.asList(query.getProductId()));
        List<ProductTariffTypeDRO> dros = meterFlow3CommonBService.listProductTariffTypeByQuery(typeQuery);
        Integer tariffType = dros.get(0).getTariffType();
        query.setTariffType(Objects.isNull(tariffType) ? ProductDict.TRIFF_TYPE_SERVICE : tariffType);
        query.setTariffId(dros.get(0).getTariffId());

    }

    private void listCategoriesAndSetQueryCategoryId(List<ChannelServiceAreaProductCategoryVo> productCategories,
                                                     final List<ChannelServiceAreaProductCategoryVo> servCategList, final List<ChannelServiceAreaProductCategoryVo> categOneList,
                                                     final List<ChannelServiceAreaProductCategoryVo> categList, ProductServiceItemExcutePriceQueryVo query) {
        // 区分前后台产品，如果是后台产品类型，那么需要对前台产品的分类进行重组变为后台产品的分类数据
        boolean isShowProudct = Objects.equals(query.getShowType(), ProductDict.EC_PRODUCT_TYPE);
        if (!isShowProudct) {
            convertShowCateg(productCategories, servCategList, categOneList, categList, query);
            return;
        }
        // 如果存在服务分类，需要在相应的服务分类下去找第一条数据，并对一二级分类赋值（一级分类存在，那么也同样需要对二级分类进行相同的操作）
        Integer filterServCategId = query.getServCategId();
        Integer filterCategOneId = query.getCategOneId();
        Integer filterCategId = query.getCategId();
        List<Integer> servIdList = new ArrayList<>();
        List<Integer> categOneIdList = new ArrayList<>();
        List<Integer> categTwoIdList = new ArrayList<>();

        for (ChannelServiceAreaProductCategoryVo vo : productCategories) {
            vo.setServCategName(vo.getShowServCategName());
            if (filterServCategId == null || filterServCategId == 0) {
                filterServCategId = vo.getServCategId();
            }
            // 服务分类
            if (!servIdList.contains(vo.getServCategId())) {
                servIdList.add(vo.getServCategId());
                servCategList.add(vo);
            }
            // 服务分类下的一级分类
            if (vo.getServCategId().equals(filterServCategId)) {
                if (filterCategOneId == null || filterCategOneId == 0) {
                    filterCategOneId = vo.getCategOneId();
                }
                if (!categOneIdList.contains(vo.getCategOneId())) {
                    categOneIdList.add(vo.getCategOneId());
                    categOneList.add(vo);
                }
                // 一级分类下的二级分类
                if (vo.getCategOneId().equals(filterCategOneId)) {
                    if (filterCategId == null || filterCategId == 0) {
                        filterCategId = vo.getCategId();
                    }
                    if (!categTwoIdList.contains(vo.getCategId())) {
                        categTwoIdList.add(vo.getCategId());
                        categList.add(vo);
                    }
                }
            }
        }
        query.setServCategId(filterServCategId);
        query.setCategOneId(filterCategOneId);
        query.setCategId(filterCategId);
    }

    private List<ChannelServiceAreaProductCategoryVo> getAllBaseCategs() {
        // 都不存在，取基础数据的所有前台分类
        List<ShowCategoryAssociationVO> allMsg = showCategoryAssociationService.listByShowCategoryId(null, null, null);
        List<ChannelServiceAreaProductCategoryVo> productCategories = allMsg.stream().map(e -> {
            ChannelServiceAreaProductCategoryVo vo = new ChannelServiceAreaProductCategoryVo();
            vo.setServCategId(e.getShowServCategId());
            vo.setCategOneId(e.getShowCategOneId());
            vo.setCategId(e.getShowCategId());
            vo.setServCategName(e.getServCategName());
            vo.setCategOneName(e.getShowCategOneName());
            vo.setCategName(e.getShowCategName());
            vo.setShowServCategName(e.getShowServCategName());
            return vo;
        }).collect(Collectors.toList());
        return productCategories;
    }

    private List<ChannelServiceArea> getALLBaseAreas() {
        AreaQuery areaQuery = new AreaQuery();
        areaQuery.setStatus(GlobalConsts.YES);
        areaQuery.setLevel(GlobalDict.AREA_LEVEL_CITY);
        areaQuery.setType(GlobalConsts.NO);
        List<BaseArea> baseAreaList = baseAreaService.listByQuery(areaQuery);
        List<ChannelServiceArea> baseAreas = baseAreaList.stream().map(e -> {
            ChannelServiceArea areas = new ChannelServiceArea();
            areas.setCityId(e.getAreaId());
            areas.setCityName(e.getName());
            return areas;
        }).collect(Collectors.toList());
        return baseAreas;
    }

    private Converter getConvert() {
        return new Converter() {
            @Override
            public Object convert(Object value, Class target, Object context) {
                // int 和 Integer转换
                if (value instanceof Integer) {
                    return (Integer) value;
                }
                return value;
            }
        };
    }

    /**
     * 描述: 将数据缩小100保留2位小数
     *
     * @param dividend 被除数
     * @return double
     * @author wangjie
     * @since 10:36 2019/4/20
     **/
    private String narrow(Object dividend) {
        if (Objects.isNull(dividend)) {
            return "--";
        }
        double div = MathUtil.div(Integer.parseInt(dividend.toString()), MasterDict.COEFFICIENT_MAGNIFICATION, 2);
        BigDecimal b = new BigDecimal(div);
        DecimalFormat df = new DecimalFormat(",###,##0.00");
        return df.format(b);
    }

}
